////////////////////////////////////////////////////////////////////////////////
// Filename: L_dx11renderer.cpp
////////////////////////////////////////////////////////////////////////////////
#include "L_dx11renderer.h"

L_DX11Renderer::L_DX11Renderer()
{
	Device = 0;
	RenderTarget = 0;
	DeviceContext = 0;
	ResourceManager = 0;
	SpriteRenderer = 0;
}

L_DX11Renderer::~L_DX11Renderer()
{

}

bool L_DX11Renderer::Init(	ID3D11Device* tDevice, ID3D11DeviceContext* tDeviceContext, 
							ID3D11RenderTargetView* tRenderTarget, L_DX11ResourceManager* tResourceManager)
{
	HRESULT hr;

	RenderTarget = tRenderTarget;
	DeviceContext = tDeviceContext;
	ResourceManager = tResourceManager;
	Device = tDevice;

	D3D11_SAMPLER_DESC sampDesc;
	ZeroMemory( &sampDesc, sizeof(sampDesc) );
	sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
	sampDesc.MinLOD = 0;
	sampDesc.MaxLOD = D3D11_FLOAT32_MAX;

	hr = Device->CreateSamplerState( &sampDesc, &TexSamplerStateLinear );
	if(FAILED(hr))
	{
		MessageBox(NULL, "Error creating sampler", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	D3D11_BUFFER_DESC cbbd;
	ZeroMemory(&cbbd, sizeof(D3D11_BUFFER_DESC));
	cbbd.Usage = D3D11_USAGE_DEFAULT;
	cbbd.ByteWidth = sizeof(cbPerObject);
	cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cbbd.CPUAccessFlags = 0;
	cbbd.MiscFlags = 0;

	hr = Device->CreateBuffer(&cbbd, NULL, &cbPerObjectBuffer);
	if( FAILED(hr) )
	{
		MessageBox(NULL, "Error creating Constant Buffer", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	SpriteRenderer = new L_SpriteRenderer;
	if( !SpriteRenderer->Init(Device, DeviceContext) )
	{
		return false;
	}

	return true;
}

void L_DX11Renderer::ClearScreen(float r, float g, float b, float alpha)
{
	float bgColor[4] = {r, g, b, alpha};
	DeviceContext->ClearRenderTargetView(RenderTarget, bgColor);
}

void L_DX11Renderer::Render(L_DX11VertexBuffer* VertexBuffer, unsigned int VertexSize)
{
	ID3D11Buffer* tVB = VertexBuffer->GetBuffer();
	unsigned int Stride = VertexSize;
	unsigned int Offset = 0;
	unsigned int NumPrimitives = static_cast<unsigned int>(VertexBuffer->GetSize()/VertexSize);
	DeviceContext->IASetVertexBuffers( 0, 1, &tVB, &Stride, &Offset );
	DeviceContext->Draw( NumPrimitives, 0 );
}

void L_DX11Renderer::SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY Topology)
{
	DeviceContext->IASetPrimitiveTopology( Topology );
}

void L_DX11Renderer::SetSamplerState(D3D11_FILTER Filter)
{
	switch(Filter)
	{
	case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
		DeviceContext->PSSetSamplers( 0, 1, &TexSamplerStateLinear );
		break;
	}
}

void L_DX11Renderer::SetTexture(string FileName)
{
	static ID3D11ShaderResourceView* tempTexture;
	tempTexture = ResourceManager->GetTexture("L.jpg");
	DeviceContext->PSSetShaderResources( 0, 1, &tempTexture );
}

void L_DX11Renderer::BeginDrawSprites()
{
	matOrtho = MatrixOrthographicLH(800, 600, 0.1f, 1000.0f);
	cbPerObj.WVP = matOrtho;
	DeviceContext->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
	DeviceContext->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
	SpriteRenderer->BeginDraw();
}

void L_DX11Renderer::EndDrawSprites()
{
	SpriteRenderer->EndDraw();
}

void L_DX11Renderer::DrawSprite(L_Sprite Sprite)
{
	SpriteRenderer->DrawSprite(Sprite);
}

void L_DX11Renderer::DrawSprites(L_Sprite* Sprites, unsigned int NumSprites)
{
	SpriteRenderer->DrawSprites(Sprites, NumSprites);
}